package co.gov.medellin.ssti.sub.paoyer.administration.dao;

import java.sql.Connection;
import java.sql.Statement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.sql.PreparedStatement;

import co.gov.medellin.ssti.sub.paoyer.administration.model.vo.ApplicationUserVO;

/**
 * DAO para crear, consultar , borrar y actualizar registros en la tabla
 * TCS_USUARIO_APLICACION.
 * 
 * @author Rene.Rangel@consultsoft.com
 * @version 1.0
 */

public class ApplicationUserDAO {
	/**
	 * Conexion a la base de datos.
	 */
	private Connection conn = null;

	/**
	 * Constructor que inicializa la conexion con la base de datos.
	 * 
	 * @param conn
	 *            Conexion con la base de datos.
	 */

	public ApplicationUserDAO(Connection conn) {
		this.conn = conn;
	}

	/**
	 * Consulta un grupo de registros de la tabla TCS_USUARIO_APLICACION a
	 * partir de las condiciones que vienen en el Value Object
	 * 
	 * @param ApplicationUserVO
	 *            Value Object con las condiciones a tener encuenta.
	 * 
	 * @return Collection Arreglo de registros retornados de la consulta.
	 */
	public Collection<ApplicationUserVO> findApplicationUserByCriterea(
			ApplicationUserVO criterea) throws SQLException {

		/**
		 * La busqueda se hace sobre las tablas Tcs_Usuario ,
		 * Tcs_usuario_aplicacion y Tcs_aplicacion con el objeto de consultar el
		 * nombre del usuario y de la aplciacion asociada
		 */

		String query = "SELECT usap.codigo, usap.descripcion, usap.usuario_crea, "
				+ "usap.terminal_crea, usap.usuario_modifica, "
				+ "usap.terminal_modifica, TO_CHAR(usap.desde_vigencia,'yyyy-mm-dd') desde_vigencia, "
				+ "TO_CHAR(usap.hasta_vigencia,'yyyy-mm-dd') hasta_vigencia, usap.vigencia, "
				+ "usap.usu_codigo, usap.apl_codigo, usua.nombre usuario, "
				+ "apli.nombre aplicacion "
				+ "FROM tcs_usuario usua, tcs_usuario_aplicacion  usap, "
				+ "tcs_aplicacion apli ";
		/*
		 * String query =
		 * "SELECT usap.*, usua.nombre usuario, apli.nombre aplicacion " +
		 * "FROM tcs_usuario usua, tcs_usuario_aplicacion usap, " +
		 * "tcs_aplicacion apli ";
		 */

		String filters = "";
		// Filtro por Codigo del Registro
		if (criterea.getCode() != null && !(criterea.getCode().intValue() == 0)) {
			filters = filters + "AND usap.codigo = " + criterea.getCode();
		}

		// Filtro por Codigo de Aplicacion
		if (criterea.getApplicationCode() != null
				&& !(criterea.getApplicationCode().intValue() == 0)) {
			filters = filters + "AND UPPER(usap.apl_codigo) = "
					+ criterea.getApplicationCode();
		}

		// Filtro por Codigo del Usuario
		if (criterea.getUserCode() != null
				&& !(criterea.getUserCode().intValue() == 0)) {
			filters = filters + " AND UPPER(usap.usu_codigo) = "
					+ criterea.getUserCode();
		}

		// Filtro por Descripcion
		if ((criterea.getDescription() != null)
				&& !(criterea.getDescription().equals(""))) {
			filters = filters + " AND usap.descripcion LIKE '%"
					+ criterea.getDescription() + "%'";
		}

		// Filtro por nombre
		if ((criterea.getUserName() != null)
				&& !(criterea.getUserName().equals(""))) {
			filters = filters + " AND usua.nombre LIKE '%"
					+ criterea.getUserName().toUpperCase() + "%'";
		}

		// Filtro por Desde Vigencia
		if (criterea.getEffectiveFrom() != null
				&& !(criterea.getEffectiveFrom().equals(""))) {
			filters = filters + " AND usap.desde_vigencia = TO_DATE('"
					+ criterea.getEffectiveFrom() + "','yyyy-mm-dd')";
		}

		// Filtro por Hasta Vigencia
		if (criterea.getEffectiveUntil() != null
				&& !(criterea.getEffectiveUntil().equals(""))) {
			filters = filters + " AND usap.hasta_vigencia = TO_DATE('"
					+ criterea.getEffectiveUntil() + "','yyyy-mm-dd')";
		}

		// Filtro por Vigencia
		if ((criterea.getUse() != null) && !(criterea.getUse().equals(""))) {
			filters = filters + " AND usap.vigencia = '" + criterea.getUse()
					+ "'";
		}

		query = query + " WHERE usua.codigo = usap.usu_codigo "
				+ "AND usap.apl_codigo = apli.codigo ";

		// Si hay filtros, entonces armar la clausula WHERE
		if (!filters.equals("")) {
			query = query + filters;
		}

		Statement stm = null;
		ResultSet rst = null;
		ArrayList<ApplicationUserVO> applicationUsers = new ArrayList<ApplicationUserVO>();

		stm = conn.createStatement();
		rst = stm.executeQuery(query);

		while (rst.next()) {
			ApplicationUserVO applicationUser = new ApplicationUserVO();
			applicationUser.setCode(new Long(rst.getLong("codigo")));
			applicationUser.setApplicationCode(new Long(rst
					.getLong("apl_codigo")));
			applicationUser.setApplicationName(rst.getString("aplicacion"));
			applicationUser.setUserCode(new Long(rst.getLong("usu_codigo")));
			applicationUser.setUserName(rst.getString("usuario"));
			applicationUser.setDescription(rst.getString("descripcion"));
			applicationUser.setEffectiveFrom(rst.getString("desde_vigencia"));
			applicationUser.setEffectiveUntil(rst.getString("hasta_vigencia"));
			applicationUser.setUse(rst.getString("vigencia"));
			applicationUser.setWebUserCrea(rst.getString("usuario_crea"));
			applicationUser.setWebClientCrea(rst.getString("terminal_crea"));
			applicationUser.setWebUserModif(rst.getString("usuario_modifica"));
			applicationUser.setWebClientModif(rst
					.getString("terminal_modifica"));
			applicationUsers.add(applicationUser);
		}

		stm.close();

		return applicationUsers;
	}

	public Collection<ApplicationUserVO> findUserNotAsociatedByCriterea(
			ApplicationUserVO criterea) throws SQLException {
		String query = "SELECT usu.codigo,"
				+ "       usu.nombre,"
				+ "       to_char(usu.desde_vigencia,'dd/mm/rrrr') dvig,"
				+ "       to_char(usu.hasta_vigencia,'dd/mm/rrrr') hvig,"
				+ "       usu.vigencia, "
				+ "       usu.campo_a1, "
				+ "       usu.fecha_crea,"
				+ "       usu.usuario_crea,"
				+ "       usu.terminal_crea,"
				+ "       usu.fecha_modifica,"
				+ "       usu.usuario_modifica,"
				+ "       usu.terminal_modifica,"
				+ "       usu.descripcion,"
				+ "       usu.gus_codigo"
				+ " FROM tcs_usuario usu where "
				+ " usu.codigo not in ( select usa.usu_codigo from tcs_usuario_aplicacion usa where usa.apl_codigo="
				+ criterea.getApplicationCode() + " )";

		Statement stm = null;
		ResultSet rst = null;
		ArrayList<ApplicationUserVO> users = new ArrayList<ApplicationUserVO>();
		stm = conn.createStatement();
		rst = stm.executeQuery(query);

		while (rst.next()) {
			ApplicationUserVO user = new ApplicationUserVO();
			user.setUserCode(new Long(rst.getLong("codigo")));
			user.setUserName(rst.getString("nombre"));
			users.add(user);
		}
		rst.close();
		stm.close();
		return users;
	}

	/**
	 * Crea un nuevo registro en la tabla TCS_GRUPO_USUARIO.
	 * 
	 * @param ApplicationUserVO
	 *            Value Object con el registro que se va a Crear.
	 * 
	 * @return ApplicationUserVO Registro creado.
	 * 
	 */
	public ApplicationUserVO createApplicationUser(
			ApplicationUserVO newApplicationUser) throws SQLException {

		String strSQL = "";
		boolean result = false;
		PreparedStatement ps = null;
		strSQL = ""
				+ "INSERT INTO tcs_usuario_aplicacion (codigo, descripcion, usuario_crea, "
				+ "terminal_crea, usuario_modifica, terminal_modifica, desde_vigencia, "
				+ "hasta_vigencia, vigencia, usu_codigo, apl_codigo) "
				+ "VALUES(scs_usuario_aplicacion.nextval,?,?,?,?,?,TO_DATE(?,'yyyy-mm-dd'), "
				+ "TO_DATE(?,'yyyy-mm-dd'),?,?,?)";

		ps = conn.prepareStatement(strSQL);
		ps.setString(1, newApplicationUser.getDescription().toUpperCase());
		ps.setString(2, newApplicationUser.getWebUserCrea().toUpperCase());
		ps.setString(3, "WEB="
				+ newApplicationUser.getWebClientCrea().toUpperCase());
		ps.setString(4, newApplicationUser.getWebUserModif().toUpperCase());
		ps.setString(5, "WEB="
				+ newApplicationUser.getWebClientModif().toUpperCase());
		ps.setString(6, newApplicationUser.getEffectiveFrom());
		ps.setString(7, newApplicationUser.getEffectiveUntil());
		ps.setString(8, newApplicationUser.getUse().toUpperCase());
		ps.setLong(9, newApplicationUser.getUserCode().longValue());
		ps.setLong(10, newApplicationUser.getApplicationCode().longValue());

		result = ps.execute();

		if (result) {
			Statement stm = conn.createStatement();
			ResultSet rst = stm
					.executeQuery("SELECT scs_usuario_aplicacion.currval FROM dual");
			if (rst.next()) {
				newApplicationUser.setCode(new Long(rst.getLong(1)));
			}
			stm.close();
			rst.close();
		}

		ps.close();

		return newApplicationUser;
	}

	/**
	 * Actualiza un registro en la tabla TCS_USUARIO_APLICACION por la llave
	 * primaria.
	 * 
	 * @param ApplicationUserVO
	 *            Value Object con el registro que se va a modificar.
	 * 
	 * @return ApplicationUserVO Registro modificado.
	 * 
	 */
	public ApplicationUserVO updateApplicationUser(
			ApplicationUserVO applicationUser) throws SQLException {

		String strSQL = "UPDATE tcs_usuario_aplicacion "
				+ "SET descripcion = ?, " + "usuario_modifica = ?, "
				+ "terminal_modifica = ?, "
				+ "desde_vigencia = TO_DATE(?,'yyyy-mm-dd'), "
				+ "hasta_vigencia = TO_DATE(?,'yyyy-mm-dd'), "
				+ "vigencia = ?, " + "usu_codigo = ?, " + "apl_codigo = ? "
				+ "WHERE codigo = ?";
		PreparedStatement ps = conn.prepareStatement(strSQL);

		ps.setString(1, applicationUser.getDescription().toUpperCase());
		ps.setString(2, applicationUser.getWebUserModif().toUpperCase());
		ps.setString(3, "WEB="
				+ applicationUser.getWebClientModif().toUpperCase());
		ps.setString(4, applicationUser.getEffectiveFrom());
		ps.setString(5, applicationUser.getEffectiveUntil());
		ps.setString(6, applicationUser.getUse().toUpperCase());
		ps.setLong(7, applicationUser.getUserCode().longValue());
		ps.setLong(8, applicationUser.getApplicationCode().longValue());
		ps.setLong(9, applicationUser.getCode().longValue());

		int updates = ps.executeUpdate();

		if (updates == 0) {
			return null;
		}

		ps.close();

		return applicationUser;

	}

	/**
	 * Borra un registro de la tabla TCS_USUARIO_APLICACION por la llave
	 * primaria.
	 * 
	 * @param ApplicationUserVO
	 *            Value Object con el registro que se va a borrar.
	 * 
	 * @return boolean Indicador de exito de la operacion de borrado
	 */
	public boolean deleteApplicationUser(ApplicationUserVO applicationUser)
			throws SQLException {

		String strSQL = "DELETE tcs_grupo_usuario " + "WHERE codigo = ?";
		PreparedStatement ps = conn.prepareStatement(strSQL);
		ps.setLong(1, applicationUser.getCode().longValue());
		boolean deletes = ps.execute();
		ps.close();
		return deletes;
	}

}